package cn.xiaopengstack.domain.strategy.service.raffle;

import cn.xiaopengstack.domain.strategy.model.entity.RuleChainMatterEntity;
import cn.xiaopengstack.domain.strategy.model.entity.StrategyAwardEntity;
import cn.xiaopengstack.domain.strategy.model.entity.StrategyRuleEntity;
import cn.xiaopengstack.domain.strategy.model.valobj.*;
import cn.xiaopengstack.domain.strategy.repository.IStrategyRepository;
import cn.xiaopengstack.domain.strategy.service.armory.IStrategyDispatch;
import cn.xiaopengstack.domain.strategy.service.rule.chain.ILogicChain;
import cn.xiaopengstack.domain.strategy.service.rule.chain.factory.DefaultLogicChainFactory;
import cn.xiaopengstack.domain.strategy.service.rule.filter.factory.DefaultLogicFactory;
import cn.xiaopengstack.domain.strategy.service.rule.tree.engine.IDecisionTreeEngine;
import cn.xiaopengstack.domain.strategy.service.rule.tree.impl.DefaultTreeFactory;
import cn.xiaopengstack.types.common.Constants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author jiangyangang
 */
@Service
@Slf4j
public class DefaultRaffleStrategy extends AbstractRaffleStrategy {

    public DefaultRaffleStrategy(IStrategyRepository strategyRepository, IStrategyDispatch strategyDispatch, DefaultLogicChainFactory defaultLogicChainFactory, DefaultTreeFactory defaultTreeFactory, DefaultLogicFactory logicFactory) {
        super(strategyRepository, strategyDispatch, defaultLogicChainFactory, defaultTreeFactory);
    }

    @Override
    public DefaultLogicChainFactory.StrategyAwardVO raffleLogicChain(RaffleStrategyContext context) {
        ILogicChain iLogicChain = defaultLogicChainFactory.openLogicChain(context.getStrategyEntity());
        return iLogicChain.doChain(RuleChainMatterEntity.builder()
                .strategy(context.getStrategyEntity())
                .user(context.getUserEntity())
                .activityId(context.getActivityEntity().getActivityId())
                .build());
    }

    @Override
    public DefaultTreeFactory.StrategyAwardVO raffleLogicTree(RaffleStrategyContext context) {

        StrategyAwardRuleModelVO strategyAwardRuleModelVO = strategyRepository.queryStrategyAwardRuleModelVO(context.getStrategyEntity().getStrategyId(), context.getAwardId());

        RuleTreeVO ruleTreeVO = strategyRepository.queryRuleTreeVOByTreeId(strategyAwardRuleModelVO.getRuleModels());
        IDecisionTreeEngine treeEngine = defaultTreeFactory.process(ruleTreeVO);
        return treeEngine.process(DefaultTreeFactory.TreeActionMatterEntity.builder()
                .strategy(context.getStrategyEntity())
                .user(context.getUserEntity())
                .awardId(context.getAwardId())
                .ruleTreeMap(ruleTreeVO.getTreeNodeMap())
                .derNumber(1)
                .build());
    }

    @Override
    public AwardStockQueueVO takeStockQueueValue(AwardStockQueueVO awardStockQueueVO) throws InterruptedException {
        return strategyRepository.consumeStrategyAwardDecrStockQueue(awardStockQueueVO);
    }

    @Override
    public void updateStrategyAwardStock(UpdateAwardStockVO updateStockVO) {
        strategyRepository.updateStrategyAwardStock(updateStockVO);
    }

    @Override
    public List<StrategyAwardEntity> queryRaffleStrategyAwardList(Long strategyId) {
        return strategyRepository.queryStrategyAwardInfoList(strategyId);
    }

    @Override
    public List<RuleWeightVO> queryAwardRuleWeightByActivityId(Long activityId) {
        List<StrategyAwardEntity> awardEntities = strategyRepository.queryStrategyAwardInfoListByActivityId(activityId);
        if (CollectionUtils.isEmpty(awardEntities)) {
            return Collections.emptyList();
        }

        // 获取策略权重规则
        StrategyRuleEntity strategyRuleEntity = strategyRepository.queryStrategyRule(awardEntities.get(0).getStrategyId(), DefaultLogicChainFactory.LogicModel.RULE_WEIGHT.getCode());
        Map<String, List<Integer>> ruleWeightValues = strategyRuleEntity.getRuleWeightValues();


        // 组装权重对象
        Map<Integer, StrategyAwardEntity> awardMap = awardEntities.stream().collect(Collectors.toMap(StrategyAwardEntity::getAwardId, Function.identity()));
        ArrayList<RuleWeightVO> ruleWeights = new ArrayList<>();
        Set<String> ruleWeightKetSet = ruleWeightValues.keySet();
        for (String key : ruleWeightKetSet) {

            List<Integer> awardIds = ruleWeightValues.get(key);
            List<StrategyAwardEntity> awards = awardIds.stream().map(awardMap::get).filter(Objects::nonNull).collect(Collectors.toList());

            String wight = key.split(Constants.COLON)[0];
            RuleWeightVO ruleWeightVO = new RuleWeightVO(Integer.parseInt(wight), awards);

            ruleWeights.add(ruleWeightVO);
        }


        return ruleWeights;
    }
}
